package store.lunangangster.engine.impl.agenda;

import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import store.lunangangster.engine.impl.entity.ExecutionEntity;
import store.lunangangster.engine.impl.entity.mgr.ExecutionEntityManager;
import store.lunangangster.engine.impl.interceptor.CommandContext;

/**
 * 当流程执行完时，通过该操作可以结束流程。前提是该流程没有活跃的子任务
 *
 * @author cwk
 * @version 1.0
 */
public class EndExecutionOperation extends AbstractOperation {

  private static final Logger log = LoggerFactory.getLogger(EndExecutionOperation.class);

  public EndExecutionOperation(ExecutionEntity execution,
      CommandContext commandContext) {
    super(execution, commandContext);
  }

  @Override
  public void run() {
    if (execution.getParentId() == null) { // 判断是否是processInstance对应的Execution
      endProcessInstanceExecution(execution);
    } else {
      endRegularExecution(execution);
    }
  }

  protected void endProcessInstanceExecution(ExecutionEntity execution) {
    String processInstanceId = execution.getProcessInstanceId();
    int activeChildExecutionNum = getNumberOfActiveChildrenExecutions(processInstanceId);
    if (activeChildExecutionNum > 0) {
      log.warn("流程{}还有{}个活跃中的子Executions，无法终止", processInstanceId, activeChildExecutionNum);
    } else {
      log.debug("流程{}没有活跃的子Executions，终止该流程", processInstanceId);
      String notes = String.format("流程\"%s\"结束", execution.getProcessInstanceName());
      commandContext.getProcessEngineConfiguration().getHistoryManager().createNewHistory(execution, null, notes);
      commandContext.getProcessEngineConfiguration()
          .getExecutionEntityManager().deleteProcessInstanceExecution(processInstanceId);
    }
  }

  protected void endRegularExecution(ExecutionEntity execution) {

    ExecutionEntityManager executionManager = commandContext.getProcessEngineConfiguration()
        .getExecutionEntityManager();

    ExecutionEntity parentExecution = executionManager.selectById(execution.getParentId());


    if (execution.isScope()) {  // 如SubProcess
      log.debug("结束Execution的children: {}", execution);
      executionManager.deleteChildExecution(execution);
    }

    log.debug("结束Execution: {}", execution);
    executionManager.deleteExecution(execution);
    log.debug("ParentExecution[{}]继续执行", parentExecution.getId());
    // 当ParentExecution没有活跃的子Execution时，需要启动ParentExecution继续执行
    if (getNumberOfActiveChildrenExecutions(parentExecution.getId()) == 0) {
      commandContext.getAgenda().addTakeOutGoingSequenceFlowOperation(parentExecution);
    }
  }

  protected int getNumberOfActiveChildrenExecutions(String parentExecutionId) {
    List<ExecutionEntity> childExecutions = commandContext.getProcessEngineConfiguration()
        .getExecutionEntityManager()
        .selectChildExecutionByParentId(parentExecutionId);
    int activeChildExecutionNum = 0;
    for (ExecutionEntity execution : childExecutions) {
      if (execution.isActive() && !execution.getId().equals(parentExecutionId)) {
        activeChildExecutionNum ++;
      }
    }
    return activeChildExecutionNum;
  }
}
